package com.heimo.agentlicence.http;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.ByteArrayBuffer;
import org.apache.http.util.EncodingUtils;
import org.apache.http.util.EntityUtils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

public class HttpHelper {
	private final static String TAG = "HttpHelper";
	protected final int CONN_PORT = 80;
	protected final String CONN_PROTOCOL = "HTTP";
	public static final String URL_BASIC = "www.eaa.org.hk";
	protected final String USER_AGENT = "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31";

	private DefaultHttpClient httpClient = null;
	private HttpHost targetHost = null;

	public HttpHelper() {
	}

	public HttpHost getTargetHost() {
		if (this.targetHost == null) {
			this.targetHost = new HttpHost(URL_BASIC, CONN_PORT, CONN_PROTOCOL);
		}
		return targetHost;
	}

	public DefaultHttpClient getClient() {
		if (this.httpClient == null) {
			this.httpClient = HttpClientFactory.getThreadSafeClient();
			// new DefaultHttpClient();
		}
		return httpClient;
	}

	public String doGet(String url) throws ParseException,
			ClientProtocolException, IOException {
		String html = "";
		// Thread.sleep(((int)(Math.random()*10))*1000);
		HttpGet httpGet = new HttpGet(url);
		fnSetGetHeader(httpGet);
		html = getResponseHTML(getClient().execute(getTargetHost(), httpGet));
		return html;
	}

	public String doPost(String url, List<NameValuePair> nvps)
			throws ClientProtocolException, IOException, ParseException {
		// Thread.sleep(((int)(Math.random()*10))*1000);
		HttpPost httpPost = new HttpPost(url);
		if (nvps != null) {
			httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
		}

		// fnDebug(nvps);

		fnSetPostHeader(httpPost);
		// fnPrintHeaderForDebug(httpPost.getAllHeaders());
		HttpResponse response = getClient().execute(getTargetHost(), httpPost);
		return getResponseHTML(response);
	}

	private void fnDebug(List<NameValuePair> nvps) {
		for (int i = 0; i < nvps.size(); i++) {
			NameValuePair n = nvps.get(i);
			String name = n.getName();
			String val = n.getValue();
			if (name != null) {
				Log.d(TAG, "=====================");
				Log.d(TAG, "[" + name + "]");
				if (val == null) {
					val = "";
					Log.d(TAG, "Null");
				} else {
					Log.d(TAG, val);
				}
			}
		}
	}

	private void fnSetGetHeader(HttpRequestBase httpRequest) {
		httpRequest
				.setHeader("Accept",
						"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
		httpRequest.setHeader("Cache-Control", "no-cache");
		httpRequest.setHeader("User-Agent", USER_AGENT);
	}

	private void fnSetPostHeader(HttpRequestBase httpRequest) {
		fnSetGetHeader(httpRequest);
		httpRequest.setHeader("X-MicrosoftAjax", "Delta=true");
		httpRequest.setHeader("Content-Type",
				"application/x-www-form-urlencoded; charset=UTF-8");
		httpRequest.setHeader("Accept", "*/*");
		httpRequest.setHeader("Accept-Charset",
				"ISO-8859-1,utf-8;q=0.7,*;q=0.3");
		// httpRequest.setHeader("Accept-Encoding", "gzip,deflate,sdch");
		httpRequest.setHeader("Accept-Language", "en-US,en;q=0.8");
		httpRequest.setHeader("Host", "www.eaa.org.hk");
		httpRequest.setHeader("Origin", "http://www.eaa.org.hk");
	}

	public String getResponseHTML(HttpResponse response) throws ParseException,
			IOException {
		HttpEntity entity = response.getEntity();
		// fnPrintHeaderForDebug(response.getAllHeaders());
		String resultHTML = EntityUtils.toString(entity, HTTP.UTF_8);
		// fnPrintHTMLForDebug(resultHTML);
		return resultHTML;
	}

	public Bitmap downloadBitmap(String url) throws IOException {
		HttpUriRequest httpGet = new HttpGet(url.toString());
		HttpResponse response = getClient().execute(getTargetHost(), httpGet);

		StatusLine statusLine = response.getStatusLine();
		int statusCode = statusLine.getStatusCode();
		if (statusCode == 200) {
			HttpEntity entity = response.getEntity();
			byte[] bytes = EntityUtils.toByteArray(entity);
			Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0,
					bytes.length);
			return bitmap;
		} else {
			throw new IOException("Download failed, HTTP response code "
					+ statusCode + " - " + statusLine.getReasonPhrase());
		}
	}

	/*
	 * Debug function
	 */
	private void fnPrintHeaderForDebug(Header[] headers) {
		for (Header h : headers) {
			System.out.println(h.getName() + ": " + h.getValue());
		}
	}

	private void fnPrintHTMLForDebug(String resultHTML) {
		// System.out.println(resultHTML);
		// Log.d(TAG, resultHTML);
		int logSize = 2000;
		if (resultHTML.length() > logSize) {
			Log.v(TAG, "sb.length = " + resultHTML.length());
			int chunkCount = resultHTML.length() / logSize; // integer division
			for (int i = 0; i <= chunkCount; i++) {
				int max = logSize * (i + 1);
				if (max >= resultHTML.length()) {
					Log.v(TAG, "chunk " + i + " of " + chunkCount + ":"
							+ resultHTML.substring(logSize * i));
				} else {
					Log.v(TAG, "chunk " + i + " of " + chunkCount + ":"
							+ resultHTML.substring(logSize * i, max));
				}
			}
		}
	}

	public void doLogout() {
		httpClient = null;
	}

	/*
	 * Low level API to get HTML response
	 */
	public String getHtmlString(String urlString) {
		try {
			URL url = new URL(urlString);
			URLConnection ucon = url.openConnection();
			InputStream instr = ucon.getInputStream();
			BufferedInputStream bis = new BufferedInputStream(instr);
			ByteArrayBuffer baf = new ByteArrayBuffer(500);
			int current = 0;
			while ((current = bis.read()) != -1) {
				baf.append((byte) current);
			}
			return EncodingUtils.getString(baf.toByteArray(), HTTP.UTF_8);
		} catch (Exception e) {
			return "";
		}
	}
}
